package com.fish.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fish.common.exception.BusinessException;
import com.fish.common.strategy.FileUploadStrategy;
import com.fish.common.strategy.FileUploadStrategyFactory;
import com.fish.dao.mapper.FileInfoMapper;
import com.fish.model.entity.FileInfo;
import com.fish.model.vo.FileInfoVO;
import com.fish.service.FileUploadService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 文件上传服务实现
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class FileUploadServiceImpl implements FileUploadService {
    
    private final FileUploadStrategyFactory strategyFactory;
    private final FileInfoMapper fileInfoMapper;
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public FileInfoVO upload(MultipartFile file, String path, String storageType) {
        // 验证文件
        validateFile(file);
        
        // 获取上传策略
        FileUploadStrategy strategy = getStrategy(storageType);
        
        try {
            // 上传文件
            Map<String, Object> uploadResult = strategy.upload(file, path);
            
            // 保存文件信息到数据库
            FileInfo fileInfo = new FileInfo();
            fileInfo.setFileName((String) uploadResult.get("fileName"));
            fileInfo.setOriginalName((String) uploadResult.get("originalName"));
            fileInfo.setFilePath((String) uploadResult.get("filePath"));
            fileInfo.setFileUrl((String) uploadResult.get("fileUrl"));
            fileInfo.setFileSize((Long) uploadResult.get("fileSize"));
            fileInfo.setFileType((String) uploadResult.get("fileType"));
            fileInfo.setStorageType(strategy.getType());
            fileInfo.setBucketName((String) uploadResult.get("bucketName"));
            
            // TODO: 从登录上下文获取当前用户信息
            // fileInfo.setUploadUserId(currentUserId);
            // fileInfo.setUploadUserName(currentUserName);
            
            fileInfoMapper.insert(fileInfo);
            
            // 转换为VO返回
            return BeanUtil.copyProperties(fileInfo, FileInfoVO.class);
            
        } catch (Exception e) {
            log.error("文件上传失败", e);
            throw new BusinessException("文件上传失败: " + e.getMessage());
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<FileInfoVO> batchUpload(List<MultipartFile> files, String path, String storageType) {
        List<FileInfoVO> result = new ArrayList<>();
        
        for (MultipartFile file : files) {
            FileInfoVO fileInfoVO = upload(file, path, storageType);
            result.add(fileInfoVO);
        }
        
        return result;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(Long fileId) {
        // 查询文件信息
        FileInfo fileInfo = fileInfoMapper.selectById(fileId);
        if (fileInfo == null) {
            throw new BusinessException("文件不存在");
        }
        
        try {
            // 获取策略并删除文件
            FileUploadStrategy strategy = getStrategy(fileInfo.getStorageType());
            strategy.delete(fileInfo.getFilePath());
            
            // 删除数据库记录
            fileInfoMapper.deleteById(fileId);
            
            log.info("文件删除成功: {}", fileInfo.getFileName());
            return true;
            
        } catch (Exception e) {
            log.error("文件删除失败", e);
            throw new BusinessException("文件删除失败: " + e.getMessage());
        }
    }
    
    @Override
    public FileInfoVO getFileInfo(Long fileId) {
        FileInfo fileInfo = fileInfoMapper.selectById(fileId);
        if (fileInfo == null) {
            throw new BusinessException("文件不存在");
        }
        return BeanUtil.copyProperties(fileInfo, FileInfoVO.class);
    }
    
    @Override
    public List<FileInfoVO> getUserFiles(Long userId) {
        LambdaQueryWrapper<FileInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FileInfo::getUploadUserId, userId)
                    .orderByDesc(FileInfo::getCreateTime);
        
        List<FileInfo> fileInfoList = fileInfoMapper.selectList(queryWrapper);
        return BeanUtil.copyToList(fileInfoList, FileInfoVO.class);
    }
    
    /**
     * 验证文件
     */
    private void validateFile(MultipartFile file) {
        if (file == null || file.isEmpty()) {
            throw new BusinessException("文件不能为空");
        }
        
        // 验证文件大小（100MB）
        long maxSize = 100 * 1024 * 1024;
        if (file.getSize() > maxSize) {
            throw new BusinessException("文件大小不能超过100MB");
        }
    }
    
    /**
     * 获取上传策略
     */
    private FileUploadStrategy getStrategy(String storageType) {
        if (storageType == null || storageType.trim().isEmpty()) {
            return strategyFactory.getDefaultStrategy();
        }
        return strategyFactory.getStrategy(storageType);
    }
}
